package com.surfilter.risk.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.surfilter.risk.constant.ConstantStr;
import com.surfilter.risk.constant.TempletHtml;
import com.surfilter.risk.dto.*;
import com.surfilter.risk.entity.DynamicPunish;
import com.surfilter.risk.entity.JudgmentDocuments;
import com.surfilter.risk.entity.Page;
import com.surfilter.risk.entity.Punish;
import com.surfilter.risk.enums.CodeStateEnum;
import com.surfilter.risk.exception.ConditionIDException;
import com.surfilter.risk.exception.ConditionTimeException;
import com.surfilter.risk.exception.ConditionTypeException;
import com.surfilter.risk.exception.QueryException;
import com.surfilter.risk.mapper.PunishDistributionMapper;
import com.surfilter.risk.mapper.PunishMapper;
import com.surfilter.risk.mapper.PunishTopMapper;
import com.surfilter.risk.service.PunishService;
import com.surfilter.risk.utils.ElasticsearchUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * PunishServiceImpl
 * Created by grom on 2017/5/2.
 */
@Service("punishService")
public class PunishServiceImpl implements PunishService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private static ResourceBundle bundle = ResourceBundle.getBundle("elasticsearch-config");

    private static String es_index_name = bundle.getString("es_index");
    private static String es_type_judgment = bundle.getString("es_type_judgmentDocuments");
    private static String es_type_punish = bundle.getString("es_type_punish");
    private static String es_type_businessInfo = bundle.getString("es_type_businessInfo");

    @Autowired
    private PunishMapper punishMapper;

    @Autowired
    private PunishTopMapper punishTopMapper;

    @Autowired
    private PunishDistributionMapper punishDistributionMapper;

    /**
     * 获取首页数据
     *
     * @return
     */
    @Transactional
    @Override
    public String getIndexMSG() {
        //punishtop    返回当年当月的信息
        List<Object> punishtopList = Lists.newArrayList();
        //riskfocus    舆情接口暂时不管
        List<Object> riskfocusList = Lists.newArrayList();
        //data
        Map<String, Object> data = Maps.newHashMap();
        //result
        Map<String, Object> result = Maps.newHashMap();
        try {
            // TODO: 2017/5/8 在es中查找当年当月的全国企业处罚信息
            //获取当前年和当前月
            Date currentDate = new Date();
            punishtopList.addAll(punishTopMapper.selectPunishListByMoney(currentDate.getYear() + 1900, currentDate.getMonth() + 1));
            // TODO: 2017/5/8 在统计表中获取累计数据
            DynamicPunish dynamicPunish = punishMapper.selectDynamicPunish();
            data.put(ConstantStr.DATACOUNT, dynamicPunish.getPunishTotal());//累积数据	datacount
            // TODO: 2017/5/8 在统计表中获取今日新增数据
            data.put(ConstantStr.TODAYGROW, dynamicPunish.getTodayTotal());//今日新增	todaygrow
            // TODO: 2017/5/8 在不知道什么地方获取到热词的数据
            data.put(ConstantStr.HOTWORD, "");//热词	hotword	[]  字符串集合

            result.put(ConstantStr.CODE, CodeStateEnum.SUCCESS);
            result.put(ConstantStr.MSG, "");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, CodeStateEnum.FAIL);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        data.put(ConstantStr.PUNISHTOP, punishtopList);
        data.put(ConstantStr.RISKFOCUS, riskfocusList);
        result.put(ConstantStr.DATA, data);
        return new Gson().toJson(result);
    }

    /**
     * 获取全国企业处罚top数据
     *
     * @param type
     * @param time
     * @return
     */
    @Transactional
    @Override
    public String getPunishTopMSG(String type, String time) {
        //result
        Map<String, Object> result = Maps.newHashMap();
        try {
            if (StringUtils.isBlank(type)) {
                //没有查询类型
                throw new ConditionTypeException("Query condition(type) is empty");
            } else {
                if (StringUtils.isBlank(time)) {
                    //没有查询时间
                    throw new ConditionTimeException("Query condition(time) is empty");
                } else {
                    String[] timeStr = time.split("-");
                    Integer year = Integer.parseInt(timeStr[0]);
                    Integer month = Integer.parseInt(timeStr[1]);
                    //能够进行查询
                    if (ConstantStr.TYPE_OF_MONEY.equals(type)) {
                        // TODO: 2017/5/8 从统计表中查找按照金额排行的20条记录
                        //data
                        List<PunishTopByMoney> data = punishTopMapper.selectPunishListByMoney(year, month);
                        result.put(ConstantStr.DATA, data);
                    } else if (ConstantStr.TYPE_OF_TIME.equals(type)) {
                        // TODO: 2017/5/8 从统计表中查找按照次数排行的20条数据
                        List<PunishTopByCount> data = punishTopMapper.selectPunishListByCount(year, month);
                        result.put(ConstantStr.DATA, data);
                    }
                    result.put(ConstantStr.MSG, "");
                    result.put(ConstantStr.CODE, ConstantStr.CODE_STATE_SUCCESS);
                }
            }
        } catch (ConditionTypeException | ConditionTimeException e1) {
            throw e1;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, ConstantStr.CODE_STATE_SUCCESS);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        return new Gson().toJson(result);
    }
//    public List<PunishTop> transfer2PunishTop(List list, String type){
//        List<PunishTop> result = Lists.newArrayList();
//        if(null != list && list.size() > 0){
//            if(ConstantStr.TYPE_OF_MONEY.equals(type)){
//                for (Object aList : list) {
//                    PunishTopByMoney punishTopByMoney = (PunishTopByMoney) aList;
//                    PunishTop punishTop = new PunishTop(punishTopByMoney.getCompany(), punishTopByMoney.getCorporation(), punishTopByMoney.getMoney().toString());
//                    result.add(punishTop);
//                }
//            }else if(ConstantStr.TYPE_OF_TIME.equals(type)){
//                for (Object aList : list) {
//                    PunishTopByCount punishTopByCount = (PunishTopByCount) aList;
//                    PunishTop punishTop = new PunishTop(punishTopByCount.getCompany(), punishTopByCount.getCorporation(), punishTopByCount.getCount().toString());
//                    result.add(punishTop);
//                }
//            }
//        }
//        return result;
//    }

    /**
     * 全国惩戒数量分布数据
     *
     * @return
     */
    @Transactional
    @Override
    public String punishDistribution() {
        //result
        Map<String, Object> result = Maps.newHashMap();
        //data
        List<NumberOfArea> data = Lists.newArrayList();
        try {
            //能够进行查询
            data = punishDistributionMapper.seletNumberOfArea();
            result.put(ConstantStr.CODE, CodeStateEnum.SUCCESS);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, CodeStateEnum.FAIL);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        result.put(ConstantStr.DATA, data);
        return new Gson().toJson(result);
    }

    /**
     * 全国惩戒实时数据更新数据
     *
     * @return
     */
    @Transactional
    @Override
    public Map<String, Object> punishDataFeed() {
        Map<String, Object> result = Maps.newHashMap();
        List<Map> data = Lists.newArrayList();
        try {
            data = punishMapper.seletDataFeed();
            result.put(ConstantStr.CODE, CodeStateEnum.SUCCESS);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, CodeStateEnum.FAIL);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        result.put(ConstantStr.DATA, data);
        return result;
    }

    /**
     * 处罚列表接口数据
     *
     * @param id
     * @param pageNo
     * @param pageSize
     * @param type
     * @return
     */
    @Transactional
    @Override
    public Map<String, Object> punishList(String id, Integer pageNo, Integer pageSize, String type) {
        Map<String, Object> result = Maps.newHashMap();
        List<Object> data = Lists.newArrayList();
        result.put(ConstantStr.CODE, 0);
        result.put(ConstantStr.MSG, StringUtils.EMPTY);
        result.put(ConstantStr.DATA, data);
        if (StringUtils.isBlank(id)) return result;
        if (null == pageNo || pageNo <= 0) pageNo = 0;
        if (null == pageSize || pageSize <= 0) pageSize = 5;
        if (StringUtils.isBlank(type)) type = "0";
        TermQueryBuilder termQueryBuilder;
        Page page = new Page();
        //查询公司emd5
        termQueryBuilder = QueryBuilders.termQuery("id", id);
        JSONObject company = ElasticsearchUtils.getTermQueryFirst(es_index_name, es_type_businessInfo, termQueryBuilder);
        if (null == company) return result;
        if (ConstantStr.NUM_ONE_STR.equals(type)) {//法院公告
            //TODO
            return result;
        } else if (ConstantStr.NUM_TWO_STR.equals(type)) {//裁判文书
            termQueryBuilder = QueryBuilders.termQuery("emd5", company.get("emd5"));
            page = ElasticsearchUtils.findByPage(es_index_name, es_type_judgment, termQueryBuilder, JudgmentDocuments.class, pageSize, pageNo);
            page = dealPageField(page, company, type);
        } else if (ConstantStr.NUM_THREE_STR.equals(type)) {//失信人信息
            //TODO
            return result;
        } else if (ConstantStr.NUM_FOUR_STR.equals(type)) {//被执行人信息
            //TODO
            return result;
        } else {
            BoolQueryBuilder builder = new BoolQueryBuilder();
            termQueryBuilder = QueryBuilders.termQuery("emd5", company.get("emd5"));
            builder.must(termQueryBuilder);
            termQueryBuilder = QueryBuilders.termQuery("authorityType", type);
            builder.must(termQueryBuilder);
            page = ElasticsearchUtils.findByPage(es_index_name, es_type_punish, builder, Punish.class, pageSize, pageNo);
            page = dealPageField(page, company, type);
        }
        result.put(ConstantStr.PAGESIZE, pageSize);
        result.put(ConstantStr.PAGE_NUMBER, page.getPageNumber());
        result.put(ConstantStr.TOTAL_PAGE, page.getTotalPage());
        result.put(ConstantStr.TOTAL_ROW, page.getTotalRow());
        result.put(ConstantStr.DATA, page.getList());
        return result;
    }

    /**
     * 根据处罚类型处理page数据
     *
     * @param page
     * @param type
     * @return
     */
    private Page dealPageField(Page page, JSONObject company, String type) {
        if (null == page) return page;
        List list = page.getList();
        List newList = Lists.newArrayList();
        for (int i = 0; i < list.size(); i++) {
            Punish o = (Punish) list.get(i);
            Map map = new HashMap();
            map.put("id", o.getId());
            map.put("filed1", o.getPunishName());
            map.put("filed2", o.getAdministrativePunishId());
            map.put("filed3", o.getLegalPerson());
            map.put("filed4", o.getDecisionDate().toLocaleString());
            map.put("filed5", o.getPunishAuthority());
            newList.add(map);
        }
        page.setList(newList);
        return page;
    }

    /**
     * 处罚详情接口数据
     *
     * @param id   处罚uuid 裁判文书 docId
     * @param type
     * @return
     */
    @Transactional
    @Override
    public Map<String, Object> punishDetails(String id, String type) {
        Map<String, Object> result = Maps.newHashMap();
        Map<String, Object> data = Maps.newHashMap();
        result.put(ConstantStr.CODE, -1);
        result.put(ConstantStr.MSG, StringUtils.EMPTY);
        result.put(ConstantStr.DATA, data);
        TermQueryBuilder termQueryBuilder;
        //获取公司信息
        TransportClient client = ElasticsearchUtils.init();
        if (StringUtils.isBlank(type)) {
            logger.info("[QX_business]: company_id is null ,type is null ");
            return result;
        }
        if (ConstantStr.NUM_ONE_STR.equals(type)) {//法院公告
            //TODO
            return result;
        }
        if (ConstantStr.NUM_TWO_STR.equals(type)) {//裁判文书
            termQueryBuilder = QueryBuilders.termQuery("docId", id);
            JSONObject doc = ElasticsearchUtils.getTermQueryFirst(es_index_name, es_type_judgment, termQueryBuilder);
            data.put("id", doc.get("id"));
            data.put("title", doc.get("title"));
            data.put("content", doc.get("bookContent"));
            return result;
        }
        if (ConstantStr.NUM_THREE_STR.equals(type)) {//失信人信息
            //TODO
            return result;
        }
        if (ConstantStr.NUM_FOUR_STR.equals(type)) {//被执行人信息
            //TODO
            return result;
        }
        termQueryBuilder = QueryBuilders.termQuery("id", id);
        JSONObject other = ElasticsearchUtils.getTermQueryFirst(es_index_name, es_type_punish, termQueryBuilder);
        data.put("id", other.get("id"));
        data.put("title", other.get("punishName"));
        data.put("content", dealPunishContent(other));
        result.put(ConstantStr.DATA, data);
        result.put(ConstantStr.CODE, 0);
        return result;
    }


    /**
     * 处理处罚展示html
     *
     * @param other
     * @return
     */
    private String dealPunishContent(JSONObject other) {
        if (null == other) return StringUtils.EMPTY;
        String detail_templet = TempletHtml.punish_detail_templet;
        detail_templet = detail_templet.replace("${administrativePunishId}", other.getString("administrativePunishId"))
                .replace("${punishName}", other.getString("punishName"))
                .replace("${punishCategoryOne}", other.getString("punishCategoryOne"))
                .replace("${punishCategoryTwo}", other.getString("punishCategoryTwo"))
                .replace("${punishCause}", other.getString("punishCause"))
                .replace("${punishBasis}", other.getString("punishBasis"))
                .replace("${administrativePeople}", other.getString("administrativePeople"))
                .replace("${uscc}", other.getString("uscc"))
                .replace("${organizationCode}", other.getString("organizationCode"))
                .replace("${businessCode}", other.getString("businessCode"))
                .replace("${taxNumber}", other.getString("taxNumber"))
                .replace("${cid}", other.getString("cid"))
                .replace("${legalPerson}", other.getString("legalPerson"))
                .replace("${decisionDate}", other.getString("decisionDate"))
                .replace("${punishAuthority}", other.getString("punishAuthority"))
                .replace("${status}", other.getString("status"))
                .replace("${updateTime}", other.getString("updateTime"))
                .replace("${memo}", other.getString("memo"));
        return detail_templet;
    }


    /**
     * 企业舆情接口数据
     *
     * @return
     */
    @Transactional
    @Override
    public String businessPublicOption() {
        //result
        Map<String, Object> result = Maps.newHashMap();
        //data
        List<PublicOption> data = Lists.newArrayList();
        try {
            // TODO: 2017/5/4 舆情数据
            data = null;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, CodeStateEnum.FAIL);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        result.put(ConstantStr.DATA, data);
        result.put(ConstantStr.PUBLIC_OPTION_COUNT, "");
        return new Gson().toJson(result);
    }

    /**
     * 企业风险聚焦接口数据
     *
     * @param pageNo
     * @param pageSize
     * @param type
     * @return
     */
    @Transactional
    @Override
    public String businessRiskMatters(Integer pageNo, Integer pageSize, String type) {
        //result
        Map<String, Object> result = Maps.newHashMap();
        //data
        BusinessDetail data = new BusinessDetail();
        try {
            if (StringUtils.isBlank(type)) {
                //没有查询类型
                throw new ConditionTypeException("Query condition(type) is empty");
            } else {
                //能够进行查询
                // TODO: 2017/5/4 进行查询
                if (ConstantStr.SEARCH_TYPE_ENVIR_PRO.equals(type)) {
//                        data
                } else if (ConstantStr.SEARCH_TYPE_FINANCE.equals(type)) {
//                        data
                } else if (ConstantStr.SEARCH_TYPE_JUDICIARY.equals(type)) {
//                        data
                } else if (ConstantStr.SEARCH_TYPE_MEDICINE.equals(type)) {
//                        data
                } else if (ConstantStr.SEARCH_TYPE_ENERGY.equals(type)) {
//                        data
                } else if (ConstantStr.SEARCH_TYPE_EDUCATION.equals(type)) {
//                        data
                }
                result.put(ConstantStr.CODE, CodeStateEnum.SUCCESS);
            }
        } catch (ConditionTypeException | ConditionIDException e1) {
            throw e1;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, CodeStateEnum.FAIL);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        result.put(ConstantStr.DATA, data);
        return new Gson().toJson(result);
    }

    /**
     * 本周热点事件数据
     *
     * @return
     */
    @Transactional
    @Override
    public String hotIssueThisWeek() {
        //result
        Map<String, Object> result = Maps.newHashMap();
        //data
        HotIssue data = new HotIssue();
        try {
            // TODO: 2017/5/4 本周热点事件数据
//            data
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, CodeStateEnum.FAIL);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        result.put(ConstantStr.DATA, data);
        result.put(ConstantStr.PUBLIC_OPTION_COUNT, "");
        return new Gson().toJson(result);
    }

    /**
     * 企业负面舆情排行榜接口数据
     *
     * @return
     */
    @Transactional
    @Override
    public String negativePublicOptionList() {
        //result
        Map<String, Object> result = Maps.newHashMap();
        //data
        negativePublicOption data = new negativePublicOption();
        try {
            // TODO: 2017/5/4 企业负面舆情排行榜数据
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, CodeStateEnum.FAIL);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        result.put(ConstantStr.DATA, data);
        result.put(ConstantStr.PUBLIC_OPTION_COUNT, "");
        return new Gson().toJson(result);
    }

    /**
     * 企业风险聚焦详情接口数据
     *
     * @param id
     * @return
     */
    @Transactional
    @Override
    public String businessRiskMattersDetails(Integer id) {
        //result
        Map<String, Object> result = Maps.newHashMap();
        //data
        RiskMattersDetail data = new RiskMattersDetail();
        try {
            if (null == id) {
                //没有查询ID
                throw new ConditionIDException("Query condition(id) is empty");
            } else {
                //能够进行查询
                // TODO: 2017/5/4 进行查询
//                if(ConstantStr.TYPE_OF_COURT_NOTICE.equals(type)){
//                        data
//                }else if(ConstantStr.TYPE_OF_JUDGEMENT_PAPER.equals(type)){
//                        data
//                }
                result.put(ConstantStr.CODE, CodeStateEnum.SUCCESS);
            }
        } catch (ConditionIDException e1) {
            throw e1;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put(ConstantStr.CODE, CodeStateEnum.FAIL);
            result.put(ConstantStr.MSG, e.getMessage());
            //所有的编译时异常，转化为运行时异常（运行时异常，spring可以做rollback的操作）
            throw new QueryException("Query inner error : " + e.getMessage());
        }
        result.put(ConstantStr.DATA, data);
        return new Gson().toJson(result);
    }
}
